package graphics;

import java.awt.*;
import java.awt.geom.*;
import java.io.*;
import java.util.*;

import javax.swing.*;

import stats.*;

import core.*;
import core.genetic.*;
import core.neural.*;
import core.sim.ring.*;

public class MainApp extends JPanel {
	
//	@Override
//	public void paintComponent(Graphics g) {
//		super.paintComponents(g);
//		Graphics2D g2 = (Graphics2D) g;
//
//		Statistics.paint(g2, new Point2D.Double(50, 50), new Point2D.Double(600, 400));
//	}
	
	JFrame simulacija;
	
	@Override
	public void paint(Graphics g) {
		super.paint(g);
		Graphics2D g2 = (Graphics2D) g;
//		g2.setColor(Color.WHITE);
		g2.setBackground(Color.WHITE);

		Statistics.paint(g2, new Point2D.Double(100, 50), new Point2D.Double(600, 400));
		GraficPainter.drawGrafic(g2, new Point2D.Double(800, 50), new Point2D.Double(300, 400), false, false, freal,findiv);		

		if (end) {					
			simulacija.repaint();
		}
	}

	public static boolean end = false;
	
	private static MainApp instance = null;
	private static JFrame frame = null;
	
	public static ArrayList<Double> freal = new ArrayList<Double>();
	public static ArrayList<Double> findiv = new ArrayList<Double>();
	

	public static MainApp getApp() {
		if (instance == null) {
			frame = new JFrame("ANT STORM");
			
			instance = new MainApp();
			frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			frame.setSize(1200, 600);
			frame.setContentPane(instance);
			frame.setVisible(true);
			
			instance.simulacija = new JFrame(); //Ringworld Simulation Window			
			instance.simulacija.setSize(800, 800);
			instance.simulacija.setResizable(false);
			instance.simulacija.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
			instance.simulacija.setContentPane(new RingworldSimulationPainter());
			instance.simulacija.setTitle("Ringworld Simulation Window");
		}
		return instance;
	}

	public static void update() {
		getApp().repaint();
	}

	public static void main(String[] args) {
		MainApp a = new MainApp();

		a.repaint();

		ArrayList<Double> min = new ArrayList<Double>();
		ArrayList<Double> sum = new ArrayList<Double>();
		ArrayList<Double> max = new ArrayList<Double>();

		for (int counter = 0;; counter++) {

			Population pop = new Population(Mode.mode.geneSize);
			new Generations().doNature(pop);
			System.out.flush();
			System.err.flush();
			System.out.println(pop.get(0).toString());

			ArrayList<Double> list = Statistics.getLists()[0];
			for (int i = 0, c = 0; i + 1 < list.size(); i += Math.max(1, Integer.highestOneBit(i) >> 5), c++) {
				if (min.size() < c)
					min.add(list.get(i));
				else
					min.set(c, Math.min(min.get(c), list.get(i)));

				if (max.size() < c)
					max.add(list.get(i));
				else
					max.set(c, Math.max(max.get(c), list.get(i)));

				if (sum.size() < c)
					sum.add(list.get(i));
				else
					sum.set(c, max.get(c) + list.get(i));

			}

			try {
				PrintStream out = new PrintStream(new BufferedOutputStream(new FileOutputStream("stat - " + counter
						+ " - " + Mode.mode.explanation + ".txt")));

				out.println(Mode.mode.explanation);

				out.println("generation\taverage\tmin\tmax");

				ArrayList<Double>[] lists = Statistics.getLists();
				for (int i = 0; i < min.size(); i++) {
					out.format("%d\t%f\t%f\t%f", i, -sum.get(i) / counter, -max.get(i), -min.get(i));
					out.println();
				}
				out.flush();
				out.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		}
	
//		System.out.flush();
//		System.out.println("----------");
//		System.out.println(freal);
//		System.out.println(findiv);
		
//		Mode.mode.evaluation.executeForMovie(pop);		
//		System.exit(0);
	}
	
	public void endForMovie() {
		simulacija.setVisible(true);
		end = true;
	}

}
